home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Networking / OTCheckNetForNBPName / OTCheckNetForNBPName.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  24.0 KB  |  924 lines  |  [TEXT/CWIE]

  1. /*
  2.  *  
  3.  *    File: OTCheckNetForNBPName.c
  4.  *            Sample code to demonstrate how to check for an AppleTalk NBPName on a
  5.  *            network. The sample works by first determining the number of zones that
  6.  *            will be searched.
  7.  */
  8.  
  9. #define DEBUG    1
  10.  
  11. #include <Types.h>
  12. #include <Events.h>
  13. #include <Windows.h>
  14. #include <Memory.h>
  15. #include <Resources.h>
  16. #include <Errors.h>
  17. #include <OSUtils.h>
  18. #include <Strings.h>
  19. #include <String.h>
  20. #include <Gestalt.h>
  21. #include <AppleTalk.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <time.h>
  25. #include <OpenTransport.h>
  26. #include <OpenTptAppleTalk.h>
  27. #include "OTCheckNetForNBPName.h"
  28.  
  29. // static globals here
  30. static ATSvcRef            gOTSvcRef    = nil;
  31. static MapperRef        gOTMapper    = nil;
  32. static UInt32            gFlags        = 0;
  33. static UInt32            gNBPLookupOutstanding = 0;
  34. static UInt32            gNumZones     = 0;
  35. static UInt32            gMatchesFound = 0;
  36. static UInt32            gNextLookup    = 0;
  37. static UInt32            gNumLookupsCompleted = 0;
  38. static OTNameID            gMyNameID    = 0;
  39. static TLookupRequest    *gLookupReqPtr = nil;
  40. static MyLookupReply    *gLookupReplyPtr = nil;
  41. static ZoneBufPtr        gZoneBufPtr  = nil;
  42. static NBPEntity        *gNBPEntityPtr;
  43. static Boolean            gDone = false;
  44. static Boolean            gTriggerAction = false;
  45. static Boolean            gNameRegistered = false;
  46.  
  47. static UInt8            gNameToSearchFor[33] = "MyName";
  48. static UInt8            gTypeToSearchFor[33] = "MyType";
  49. static UInt8            gNameToRegister[33] = "MyName";
  50. static UInt8            gTypeToRegister[33] = "MyType";
  51.  
  52.  
  53. //
  54. //    Prototypes here
  55. //
  56.  
  57. extern         OSStatus DoNegotiateSelfSendOption(EndpointRef ep, long enableSelfSend);
  58. OSStatus     ActivateCheckNetStuff(void);
  59. void         CleanupNetStuff(void);
  60. void        CleanupLookupStuff(void);
  61. UInt32        GetNumZonesToCheckFor(void);
  62. UInt32         CountZonesFromUnpackedBuffer(UInt8 *buffer, long len);
  63. UInt32         MoveZonesToUnpackedBuffer(UInt8 *packedBuffer, ZoneBufPtr zoneBufPtr, long len);
  64. OSStatus     DoOTGetZoneList(void);
  65. OSStatus     SetNameMatchString(Str32 *matchString);
  66. OSStatus     SetTypeMatchString(Str32 *matchString);
  67. OSStatus     SetNameRegisterString(Str32 *registerString);
  68. OSStatus     SetTypeRegisterString(Str32 *registerString);
  69. UInt32         GetNumberOfActiveLookups(void);
  70. UInt32         GetNumberOfEntitiesPerZone(void);
  71. UInt32         GetLookupTimeout(void);
  72. UInt32         GetEntitySize(Str32 *nameString, Str32 *typeString);
  73. OSStatus     InitiateLookupStuff(Str32 *nameString, Str32 *typeString);
  74. OSStatus     MakeOTLookupCall(UInt32 indx, UInt32 lindx, Str32 *nameString, Str32 *typeString);
  75. OSStatus     OTRegisterMyName (void);
  76. void         OTDeleteMyName (void);
  77. OSStatus     DoLookupTest(void);
  78. short        clen(char *cptr);
  79. void        c2p(char *cptr);
  80. UInt16         OTMySetNBPEntity(char *buffer, Ptr nbpObject, Ptr nbpType, Ptr nbpZone);
  81. pascal void MyNBPHandler(void* contextPtr, OTEventCode event, OTResult result, void* cookie);
  82. void        DoEvent(EventRecord *event);
  83.  
  84.  
  85. OSStatus ActivateCheckNetStuff(void)
  86. {
  87.     OSStatus        err = noErr;
  88.     
  89.     if (gOTSvcRef == nil)
  90.     {
  91.             // open the appletalk services provider
  92.         gOTSvcRef = OTOpenAppleTalkServices(OTCreateConfiguration(kZIPName), 0, &err);
  93.     }
  94.     
  95.     if ((err == noErr) && (gOTMapper == nil))
  96.     {
  97.         
  98.             // open an NBP Mapper service provider
  99.         gOTMapper = OTOpenMapper(OTCreateConfiguration(kNBPName), 0, &err);
  100.  
  101.         
  102.         if (err == noErr) 
  103.         {
  104.                 // install notifier for the mapper
  105.                 // note that since OpenTransport sets the A5 world for a 68K handler,
  106.                 // we don't need to mess with saving/setting/restoring A5 - yea!!
  107.             err = OTInstallNotifier(gOTMapper, (OTNotifyProcPtr)MyNBPHandler, nil);
  108.         }
  109.     }
  110.  
  111.     return err;
  112.  
  113. }
  114.  
  115. /*
  116.     Cleanup what we opened in the ActivateCheckNetStuff routine - this routine also frees up the 
  117.     memory associated with the zone list. It also checks whether an entity has been registered and
  118.     deletes it.
  119. */
  120. void CleanupNetStuff(void)
  121. {
  122.     if (gZoneBufPtr)
  123.     {
  124.         OTFreeMem(gZoneBufPtr);
  125.         gZoneBufPtr = nil;
  126.     }
  127.  
  128.     if (gOTSvcRef)
  129.     {
  130.         OTCloseProvider(gOTSvcRef);
  131.         gOTSvcRef = nil;
  132.     }
  133.     
  134.     if (gOTMapper)
  135.     {
  136.         if (gNameRegistered == true)
  137.         {
  138.             OTDeleteMyName();
  139.             gNameRegistered = false;
  140.         }
  141.             
  142.         OTCloseProvider(gOTMapper);
  143.         gOTMapper = nil;
  144.     }
  145. }
  146.  
  147. /*
  148.     Cleanup what we opened in the InitiateLookup routine 
  149. */
  150. void CleanupLookupStuff(void)
  151. {
  152.     if (gLookupReqPtr)
  153.     {
  154.         OTFreeMem(gLookupReqPtr);
  155.         gLookupReqPtr= nil;
  156.     }
  157.  
  158.     if (gLookupReplyPtr)
  159.     {
  160.         OTFreeMem(gLookupReplyPtr);
  161.         gLookupReplyPtr = nil;
  162.     }
  163.  
  164.     if (gNBPEntityPtr)
  165.     {
  166.         OTFreeMem(gNBPEntityPtr);
  167.         gNBPEntityPtr = nil;
  168.     }
  169. }
  170.  
  171. /*
  172.     CountZonesFromUnpackedBuffer takes a input the zone name buffer and the valid length of the
  173.     buffer contents and returns the number of zone names in the buffer
  174. */
  175. UInt32 CountZonesFromUnpackedBuffer(UInt8 *buffer, long len)
  176. {
  177.     long    index = 0L;
  178.     short    i = 0;
  179.     
  180.     while (index < len) 
  181.     {
  182.         index += (char)((Ptr)buffer+index)[0]+1L;
  183.         i++;
  184.     }
  185.     return i;
  186. }
  187.  
  188. /*
  189.     MoveZonesToUnpackedBuffer takes as input the zone name buffer and the valid length of the
  190.     buffer contents and moves the zones names into the ZoneBufPtr array elements.
  191.     the zoneBufPtr will be an array of Pascal strings
  192. */
  193. UInt32 MoveZonesToUnpackedBuffer(UInt8 *packedBuffer, ZoneBufPtr zoneBufPtr, long len)
  194. {
  195.     long    index = 0L;
  196.     short    i = 0;
  197.     
  198.     while (index < len) 
  199.     {
  200.         BlockMoveData((Ptr)packedBuffer+index, (Ptr)&zoneBufPtr[i].zoneName, zoneNameSize);
  201.         index += (char)((Ptr)packedBuffer+index)[0]+1L;
  202.         i++;
  203.     }
  204.     return i;
  205. }
  206.  
  207. /*
  208.     GetNumZonesToCheckFor returns the number of zones to start checking for. The smaller the number the more you may have to 
  209.     search until all of the zones are read
  210. */
  211. UInt32    GetNumZonesToCheckFor(void)
  212. {
  213.         // could store this in a resource and obtain the value here.
  214.     return kNumZonesToCheckFor;
  215. }
  216.  
  217. /*
  218.     DoOTGetZoneList repeatedly calls OTAtalkGetZoneList until kOTBufferOverflowErr is no longer
  219.     returned, which indicates that the provided buffer was too small for the number of AppleTalk zones present.
  220.     Note that the global gZoneBufPtr is allocated here and is not de-allocated until the CleanupNetStuff call.
  221. */
  222. OSStatus DoOTGetZoneList(void)
  223. {
  224.     TNetbuf        reply;
  225.     OSStatus    err = noErr;
  226.     UInt8        *packedzonebuffptr = nil;
  227.     UInt32        numZonesToCheckFor;
  228.     short        increment = 0;
  229.     Boolean        done = false;
  230.     
  231.     numZonesToCheckFor = GetNumZonesToCheckFor();
  232.         // set up to loop until we have a buffer big enough to hold all of the returned zones
  233.     while (done == false)
  234.     {
  235.         numZonesToCheckFor += increment;
  236.         
  237.         if (packedzonebuffptr != nil)
  238.             OTFreeMem(packedzonebuffptr);
  239.             
  240.         packedzonebuffptr = OTAllocMem(numZonesToCheckFor * zoneNameSize);
  241.  
  242.         if (packedzonebuffptr != nil)
  243.         {
  244.             reply.buf = packedzonebuffptr;
  245.             reply.maxlen = numZonesToCheckFor * zoneNameSize;
  246.                 // by default, the AtalkServiceProvider is in synchronous mode
  247.             err = OTATalkGetZoneList(gOTSvcRef, &reply);
  248.             if (err == kOTBufferOverflowErr)
  249.             {
  250.                 fprintf(stdout, "Buffer Overflow error occurred with numZonesToCheckFor = %d\n", numZonesToCheckFor);
  251.                     // reset the err to noErr
  252.                 err = noErr;
  253.                 increment = numZonesIncrement;
  254.             }
  255.             else if( err == noErr)
  256.             {
  257.                 done = true;
  258.             }
  259.             else
  260.             {
  261.                 done = true;
  262.                 fprintf(stdout, "error %d occurred on call to OTATalkGetZoneList\n", err);
  263.                 
  264.             }
  265.                 
  266.         }
  267.         else
  268.         {
  269.             done - true;
  270.             fprintf(stdout, "mem error occurred while allocating packedzonebuffptr for %d zones\n", numZonesToCheckFor);
  271.             err = memFullErr;
  272.         }
  273.     }
  274.     
  275.     if (err == noErr)
  276.     {
  277.         gNumZones = CountZonesFromUnpackedBuffer(packedzonebuffptr, reply.len);
  278.         fprintf(stdout, "There are %d zones detected\n", gNumZones);
  279.             // allocate the memory for the zone list structure
  280.             // check first if any zones were found
  281.         if (gNumZones == 0)
  282.             gZoneBufPtr = OTAllocMem(sizeof(ZoneBuffer));
  283.         else
  284.             gZoneBufPtr = OTAllocMem(gNumZones * sizeof(ZoneBuffer));
  285.             
  286.         if (gZoneBufPtr == nil)
  287.         {
  288.             fprintf(stdout, "mem error occurred while allocating ZoneBuffer array for %d zones\n", numZonesToCheckFor);
  289.             err = memFullErr;
  290.         }
  291.         else
  292.         {
  293.             if (gNumZones == 0)
  294.             {
  295.                 gZoneBufPtr->zoneName[0] = 1;
  296.                 gZoneBufPtr->zoneName[1] = '*';
  297.                 gZoneBufPtr->zoneName[2] = 0;
  298.  
  299.             }
  300.             else
  301.                 MoveZonesToUnpackedBuffer(packedzonebuffptr, gZoneBufPtr, reply.len);
  302.         }
  303.     }
  304.     
  305.         // we're done with the packedzonebuffptr, so lets get rid of it.
  306.     if (packedzonebuffptr != nil)
  307.         OTFreeMem(packedzonebuffptr);
  308.     
  309.     return err;
  310. }
  311.  
  312. /*
  313.     SetNameMatchString is where you set the name string that the program will search for among the zones.
  314.     replace this code with that where you define the NBP name string to search for
  315. */
  316. OSStatus SetNameMatchString(Str32 *matchString)
  317. {
  318.     BlockMoveData((Ptr)gNameToSearchFor, (Ptr)matchString, clen((char*)gNameToSearchFor)+1);
  319.     c2p((char*)matchString);
  320.     return noErr;
  321. }
  322.  
  323. /*
  324.     SetTypeMatchString is where you set the type string that the program will search for among the zones.
  325.     replace this code with that where you define the NBP type string to search for
  326.  
  327. */
  328. OSStatus SetTypeMatchString(Str32 *matchString)
  329. {
  330.     BlockMoveData((Ptr)gTypeToSearchFor, (Ptr)matchString, clen((char*)gTypeToSearchFor)+1);
  331.     c2p((char*)matchString);
  332.     return noErr;
  333. }
  334.  
  335. /*
  336.     SetNameRegisterString is where you set the name string that the program will register with NBP
  337. */
  338. OSStatus SetNameRegisterString(Str32 *registerString)
  339. {
  340.     BlockMoveData((Ptr)gNameToRegister, (Ptr)registerString, clen((char*)gNameToRegister)+1);
  341.     c2p((char*)registerString);
  342.     return noErr;
  343. }
  344.  
  345. /*
  346.     SetTypeMatchString is where you set the type string that the program will search for among the zones.
  347.  
  348. */
  349. OSStatus SetTypeRegisterString(Str32 *registerString)
  350. {
  351.     BlockMoveData((Ptr)gTypeToRegister, (Ptr)registerString, clen((char*)gTypeToRegister)+1);
  352.     c2p((char*)registerString);
  353.     return noErr;
  354. }
  355.  
  356. /*
  357.     GetNumberOfActiveLookups returns the number of simultaneous lookups that are active at one time.  The more you do at
  358.     one time, the faster you get the search done.  On the other hand, doing to many lookups at once may flood the
  359.     network.  GetNumberOfActiveLookups allows you to define how many lookups are active at the same time.
  360.  
  361. */
  362. UInt32 GetNumberOfActiveLookups(void)
  363. {
  364.     if (gNumZones <= kMaxActiveLookups)
  365.     {
  366.         // if there are no zones
  367.         if (gNumZones == 0)
  368.             return 1;
  369.         else
  370.             return gNumZones;
  371.     }
  372.     else return kMaxActiveLookups;
  373. }
  374.  
  375. /*
  376.     GetNumberOfEntitiesPerZone returns the maximum number of matches that I want to look for in a zone.  If multiple matches are
  377.     permitted, then you have to face the possibility that the maximum number of matches might exist in the same zone.
  378. */
  379. UInt32 GetNumberOfEntitiesPerZone(void)
  380. {
  381.     return 1;
  382. }
  383.  
  384. /*
  385.     return the lookup timeout value that the program will use
  386. */
  387. UInt32 GetLookupTimeout(void)
  388. {
  389.     return kDefaultTimeout;
  390. }
  391.  
  392. /*
  393.     GetEntitySize returns the entity size to use
  394.     Note that we have only allocated a "minimum" size entity array rather than a full 
  395.     size array, in order to reduce the memory allocation requirement.  Since we do this
  396.     we can't treat the entity array as a simple array.  In order to access each element
  397.     we have to take the size of each element, multiply that value against the array index
  398.     for the element and add the result to the base pointer to get each array element.
  399. */
  400. UInt32 GetEntitySize(Str32 *nameString, Str32 *typeString)
  401. {
  402.     UInt8    *c1, *c2;
  403.     
  404.     c1 = (UInt8*)nameString;
  405.     c2 = (UInt8*)typeString;
  406.             
  407.     return (c1[0] + 1 + c2[0] + 1 + kNBPMaxZoneLength + 8);
  408. }
  409.  
  410. /*
  411.     Set up the lookup arrays that we will need for the NBP lookups.  The request, reply and
  412.     entity structures cannot go away while the lookup is active since we are making them asynchronously
  413.     
  414. */
  415. OSStatus InitiateLookupStuff(Str32 *nameString, Str32 *typeString)
  416. {
  417.     UInt32        numLookupsActive;
  418.     UInt32        entitySize;
  419.     UInt32        numEntitiesPerZone;
  420.     OSStatus    err;
  421.     short        i;
  422.     
  423.     numLookupsActive = GetNumberOfActiveLookups();
  424.     
  425. #ifdef DEBUG
  426.     DebugStr("\p about to allocate memory");
  427. #endif
  428.  
  429.     gLookupReqPtr = (TLookupRequest*) OTAllocMem(numLookupsActive * sizeof(TLookupRequest));
  430.     gLookupReplyPtr = (MyLookupReply*) OTAllocMem(numLookupsActive * sizeof(MyLookupReply));
  431.     
  432.     if ((gLookupReqPtr != nil) && (gLookupReplyPtr != nil))
  433.     {
  434.         err = noErr;
  435.         
  436.             // figure out the max number of entities we want to match on in a zone.  If we want to find any
  437.             // duplicate of a name, then return 1.  But if we allow more than one entity at all, then plan on
  438.             // that maximum number existing in the same zone.
  439.         numEntitiesPerZone = GetNumberOfEntitiesPerZone();
  440.  
  441.             // figure out how much memory to allocate for the entity buffer.
  442.             // since we know the name and type strings, we can figure their length and add the max zone string
  443.             // length instead of allocating the full max entity length string
  444.             // make sure to also add space for the address, plus the 4 bytes at the beginning of each response
  445.             // which is for the 2 length values - total of 8 bytes.
  446.         entitySize = GetEntitySize(nameString, typeString);
  447.         
  448.             // allocate the entityptr array.  Note that we will use the same entity structure for input and 
  449.             // potential output
  450.         gNBPEntityPtr = (NBPEntity*) OTAllocMem(numLookupsActive * entitySize * numEntitiesPerZone);
  451.         if (gNBPEntityPtr == nil)
  452.             err = memFullErr;
  453.     }
  454.     else
  455.         err = memFullErr;
  456.         
  457.     
  458.     if (err == noErr)
  459.     {
  460.         for (i = 0; i < numLookupsActive;)
  461.         {
  462.             gLookupReplyPtr[i].index = i;
  463.             i++;
  464.         }
  465.         
  466.             // we initiate all of the lookups in the following loop, however, if there are more lookups than
  467.             // we have lookuprequests in the array, then set the gNextLookup indice to numLookupsActive
  468.             // so that this will be where we begin other lookups if the entity is not found.
  469.         gNextLookup = numLookupsActive;
  470.         
  471.             // set the gOTMapper endpoint to operate asynchronously
  472.         OTSetAsynchronous(gOTMapper);
  473.         
  474.         for (i = 0; (gDone == false) && (i < numLookupsActive);)
  475.         {
  476.             err = MakeOTLookupCall(i, i, nameString, typeString);
  477.             i++;
  478.         }
  479.     }
  480.     return err;
  481.     
  482. }
  483.  
  484. /*
  485.     MakeOTLookupCall is where we make the zone specific Lookup call.
  486.     input parameters
  487.         indx - index into the gLookupReqPtr, gNBPEntityPtr, and the gLookupReplyPtr arrays
  488.         lindx - index into the gZoneBufPtr where we get the zone where we will perform the next lookup
  489.         nameString - pascal name string
  490.         typeString - pascal type string
  491. */
  492.  
  493. OSStatus MakeOTLookupCall(UInt32 indx, UInt32 lindx, Str32 *nameString, Str32 *typeString)
  494. {
  495.     OSStatus    err;
  496.     UInt32        entitySize;
  497.     UInt32        numEntitiesPerZone;
  498.     char*        entityPtrToUse;
  499.  
  500.     
  501.         // figure out the max number of entities we want to match on in a zone.  If we want to find any
  502.         // duplicate of a name, then return 1.  But if we allow more than one entity at all, then plan on
  503.         // that maximum number existing in the same zone.
  504.     numEntitiesPerZone = GetNumberOfEntitiesPerZone();
  505.     
  506.         // figure out how much memory to allocate for the entity buffer.
  507.         // since we know the name and type strings, we can figure their length and add the max zone string
  508.         // length instead of allocating the full max entity length string
  509.     entitySize = GetEntitySize(nameString, typeString);
  510.     
  511.     OTMemset(&gLookupReqPtr[indx], 0, sizeof(TLookupRequest));
  512.         // set up the lookup request record
  513.     gLookupReqPtr[indx].maxcnt = numEntitiesPerZone;
  514.     gLookupReqPtr[indx].timeout = GetLookupTimeout();
  515.         // figure out where the the pointer is in the array to use.
  516.     entityPtrToUse = (char*) ((UInt32) gNBPEntityPtr + indx * entitySize * numEntitiesPerZone);
  517.     
  518.     gLookupReqPtr[indx].name.len = (size_t)OTMySetNBPEntity(entityPtrToUse, 
  519.                                 (char*)nameString, (char*)typeString, (char*)&gZoneBufPtr[lindx].zoneName);
  520.     gLookupReqPtr[indx].name.buf = (unsigned char*)entityPtrToUse;
  521.     
  522.     gLookupReqPtr[indx].addr.len = 0;
  523.     gLookupReqPtr[indx].addr.buf = nil;
  524.     gLookupReqPtr[indx].addr.maxlen = 0;
  525.     
  526.         // set up the lookup reply record
  527.     gLookupReplyPtr[indx].lkReply.names.maxlen = numEntitiesPerZone * entitySize;
  528.     gLookupReplyPtr[indx].lkReply.names.len = 0;
  529.     gLookupReplyPtr[indx].lkReply.names.buf = (unsigned char*)entityPtrToUse;
  530.     gLookupReplyPtr[indx].lkReply.rspcount = 0;
  531.  
  532.     gLookupReplyPtr[indx].lindex = lindx;
  533.     
  534.         // make the lookup call
  535.     err = OTLookupName(gOTMapper, &gLookupReqPtr[indx], (TLookupReply*)&gLookupReplyPtr[indx]);
  536.     if (err != noErr)
  537.     {
  538. #ifdef DEBUG
  539.             // this call can be made at deferred task time, so we can't make a call that
  540.             // might allocate memory
  541.         DebugStr("\p Error occurred making OTLookupName call");
  542. #endif
  543.     }
  544.     return err;
  545. }
  546.  
  547. /*******************************************************************************
  548. ** Register my name using Open Transport
  549. ********************************************************************************/
  550. OSStatus OTRegisterMyName (void)
  551. {
  552.     TRegisterRequest regreq;
  553.     TRegisterReply    regreply;
  554.     OSErr            err;
  555.     Str32            nameString;
  556.     Str32            typeString;
  557.     
  558.     UInt8            nameBuf[100];
  559.     
  560.     err = SetNameRegisterString(&nameString);
  561.  
  562.     if (err == noErr)
  563.     {
  564.         err = SetTypeRegisterString(&typeString);    
  565.     }
  566.         // create the NBP name string and set the len field for the string
  567.         // and register in the local zone
  568.     regreq.name.len = OTMySetNBPEntity((char*)nameBuf, (Ptr)&nameString, (Ptr)&typeString, (Ptr)"\p*");
  569.     regreq.name.maxlen = sizeof(nameBuf);
  570.     regreq.name.buf = nameBuf;
  571.     
  572.         // let the system define the network address for this name
  573.     regreq.addr.len = regreq.addr.maxlen = 0;
  574.     regreq.addr.buf = NULL;
  575.     
  576.         // set up regreply
  577.     regreply.addr.maxlen = 0;
  578.     regreply.addr.buf = nil;
  579.         
  580.     OTSetSynchronous(gOTMapper);
  581.     err = OTRegisterName(gOTMapper, ®req, ®reply);
  582.     if (err == noErr)
  583.     {
  584.         gMyNameID = regreply.nameid;
  585.         gNameRegistered = true;
  586.     }
  587.     
  588.     return err;
  589. }
  590.  
  591. /*******************************************************************************
  592. ** Delete my name using Open Transport
  593. ********************************************************************************/
  594. void OTDeleteMyName (void)
  595. {    
  596.     OTSetSynchronous(gOTMapper);
  597.     OTDeleteNameByID(gOTMapper, gMyNameID);
  598.     gNameRegistered = false;    
  599. }
  600.  
  601. OSStatus DoLookupTest(void)
  602. {
  603.     EventRecord        theEvent;
  604.     OSStatus        err;
  605.     Str32            nameString;
  606.     Str32            typeString;
  607.     long            ticks;
  608.     Boolean            watchTrigger = true;
  609.  
  610.         // we start the lookup test here by getting the NBP name and type to look for
  611.     err = SetNameMatchString(&nameString);
  612.     
  613.     if (err == noErr)
  614.     {
  615.         err = SetTypeMatchString(&typeString);
  616.     }
  617.  
  618.         // we start the asynch lookup process here.
  619.     if (err == noErr)
  620.     {
  621.         err = InitiateLookupStuff(&nameString, &typeString);
  622.     }
  623.     
  624.         // we sit in a WNE (WaitNextEvent) loop for the search to complete.
  625.     if (err == noErr)
  626.     {
  627.         ticks = TickCount() + 300;
  628.         printf("Use Command-Q to quit.\n");
  629.         
  630.         while (gDone == false)
  631.         {
  632.             if (!WaitNextEvent(everyEvent, &theEvent, 15, nil))
  633.                 theEvent.what = nullEvent;
  634.                 
  635.             DoEvent(&theEvent);
  636.  
  637.             if (ticks < TickCount())
  638.             {
  639.                 ticks = TickCount() + 300;
  640.                 fprintf(stdout, "%d/%d ", gMatchesFound, gNumLookupsCompleted);
  641.                 fflush(stdout);
  642.             }
  643.             
  644.             if (watchTrigger == true)
  645.             {
  646.                 if (gTriggerAction == true)
  647.                 {
  648.                     fprintf(stdout, "\n Too many matches were found \n");
  649.                     fflush(stdout);
  650.                     watchTrigger = false;
  651.                 }
  652.             }
  653.             
  654.             if (gNumLookupsCompleted >= gNumZones)
  655.             {
  656.                 gDone = true;
  657.                 fprintf(stdout, "\nThere were %d matches found in %d zones\n\n", gMatchesFound, gNumLookupsCompleted);
  658.                 fflush(stdout);
  659.             }
  660.             
  661.         }
  662.     }
  663.     return err;
  664. }
  665.  
  666. int main(void)
  667. {
  668.     OSStatus        err;
  669.             
  670.         
  671.     printf ("Sample Program: OTCheckNetForNBPName!\n\n");
  672.     
  673.     err = InitOpenTransport();
  674.  
  675.     if (err != noErr)
  676.     {
  677.         printf ("InitOpenTransport failed with error %d\n", err);
  678.         return err;
  679.     }
  680.     
  681.     err = ActivateCheckNetStuff();
  682.     if (err != noErr)
  683.     {
  684.         fprintf(stdout, "ActivateCheckNetStuff returned error %d.\n", err);
  685.     }
  686.     
  687.     if (err == noErr)
  688.     {
  689.         err = DoOTGetZoneList();
  690.         if (err != noErr)
  691.         {
  692.             fprintf(stdout, "DoOTGetZoneList returned error %d.\n", err);
  693.         }
  694.     }
  695.     
  696.     err = DoLookupTest();
  697.     
  698.     if ((err == noErr) && (gNumLookupsCompleted < gNumZones))
  699.     {
  700.         fprintf(stdout, "\nYou stopped the lookup test before all of the lookups were complete!\n");
  701.         fprintf(stdout, "Am closing the mapper endpoint to clear all outstanding lookups.\n");
  702.             // close the mapper endpoint and reopen it
  703.         OTCloseProvider(gOTMapper);
  704.         gOTMapper = nil;
  705.         fprintf(stdout, "Am reopening the mapper endpoint.\n");
  706.         err = ActivateCheckNetStuff();
  707.     }
  708.     
  709.     if (err == noErr)
  710.     {
  711.         err = OTRegisterMyName();
  712.         if (err)
  713.             fprintf(stdout, "Error occurred registering the name %d\n", err);
  714.         else
  715.         {
  716.             fprintf(stdout, "\nEntity successfully registered\n");
  717.             // the following code will enable SelfSend mode globally on the machine
  718.             // otherwise it is only enabled for this process
  719.             err = DoNegotiateSelfSendOption(gOTMapper, 1);
  720.             if (err == 1)
  721.             {
  722.                 fprintf(stdout, "self send previously enable\n");
  723.                     // reset err
  724.                 err = noErr;
  725.             }
  726.             else
  727.             {
  728.                 fprintf(stdout, "Error occurred negotiating self send %d\n", err);
  729.                 fprintf(stdout, "Quitting program\n");
  730.             }
  731.         }
  732.     }
  733.         
  734.     if (err == noErr)
  735.     {
  736.         fprintf(stdout, "\nPerforming the next lookup\n");
  737.             // reset gDone and try the lookup test again
  738.         gDone = false;
  739.         gNumLookupsCompleted = 0;
  740.         err = DoLookupTest();
  741.     }
  742.     
  743.     CleanupLookupStuff();
  744.     
  745.     CleanupNetStuff();
  746.  
  747.     CloseOpenTransport();
  748.         
  749.     fprintf(stdout, "\nTest ended\n");
  750.     return 0;
  751. }
  752.  
  753. /*****************************************************************************/
  754. /* Convert a c-string to a pascal-string. */
  755. short    clen(char *cptr)
  756. {
  757.     short    i;
  758.  
  759.     for (i = 0; cptr[i]; ++i) {};
  760.     return(i);
  761. }
  762.  
  763. /*****************************************************************************/
  764. void    c2p(char *cptr)
  765. {
  766.     char    len;
  767.  
  768.     BlockMove(cptr, cptr + 1, len = clen(cptr));
  769.     *cptr = len;
  770. }
  771.  
  772. /*
  773.     OTMySetNBPEntity is used to set up an NBP lookup query buffer.
  774.     All input strings are assumed to be pascal strings
  775. */
  776. UInt16 OTMySetNBPEntity(char *buffer, Ptr nbpObject, Ptr nbpType, Ptr nbpZone)
  777. {
  778.     char*    bufPtr;
  779.     UInt16    len;
  780.     
  781.     bufPtr = buffer;
  782.  
  783.     BlockMove((Ptr)&nbpObject[1], bufPtr, nbpObject[0]);
  784.     bufPtr += nbpObject[0];        // point buffer to end of current string
  785.     len = nbpObject[0];            // collect number of chars moved to buffer
  786.  
  787.         // add the ":" character between the object and type strings
  788.     *bufPtr = ':';
  789.     bufPtr++;
  790.     len++;
  791.  
  792.     BlockMove((Ptr)&nbpType[1], bufPtr, nbpType[0]);
  793.     bufPtr += nbpType[0];        // point buffer to end of current string
  794.     len += nbpType[0];            // collect number of chars moved to buffer
  795.     
  796.         // add the "@" character between the type and zone strings
  797.     *bufPtr = '@';
  798.     bufPtr++;
  799.     len++;
  800.  
  801.     BlockMove((Ptr)&nbpZone[1], bufPtr, nbpZone[0]);
  802.     len += nbpZone[0];            // collect number of chars moved to buffer
  803.     return len;    
  804. }
  805.  
  806.  
  807. /*******************************************************************************
  808. ** HandleMapperEvents TMapper (NBP) Event Handling
  809. ********************************************************************************/
  810.  
  811.  
  812. pascal void MyNBPHandler(void* contextPtr, OTEventCode event, OTResult result, void* cookie)
  813. {
  814.  
  815.     MyLookupReplyPtr    myReplyPtr;
  816.     OSStatus            err;
  817.     UInt32                indx;
  818.     Boolean                dolookup = false;
  819.     Str32                nameString;
  820.     Str32                typeString;
  821.     
  822.     switch (event)
  823.     {
  824.         case T_LKUPNAMERESULT:        // intermediate result notification
  825.             break;
  826.             
  827.         case T_LKUPNAMECOMPLETE:
  828. #ifdef DEBUG
  829. //            DebugStr("\p about to set gNumLookupsCompleted");
  830. #endif
  831.             gNumLookupsCompleted++;
  832.                 // in a lookupcomplete event, the cookie is a OTLookupReply ptr.
  833.             myReplyPtr = (MyLookupReplyPtr)cookie;
  834.             
  835.             if ((result == kOTBufferOverflowErr) ||
  836.                 (result == noErr))
  837.             {
  838.                 gMatchesFound += myReplyPtr->lkReply.rspcount;
  839.                 dolookup = true;
  840.                 if (gMatchesFound > GetNumberOfEntitiesPerZone())
  841.                     gTriggerAction = true;
  842.             }
  843.             
  844.             if (result == kOTNoDataErr)
  845.                 dolookup = true;
  846.             
  847.             if (dolookup == true)
  848.             {
  849.                 if (gNextLookup < gNumZones)
  850.                 {
  851.                     indx = myReplyPtr->index;
  852.                     if (indx >= kMaxActiveLookups)
  853.                     {
  854. #ifdef DEBUG
  855.                         DebugStr("\p about to set gNumLookupsCompleted");
  856. #endif
  857.                     }
  858.                     else
  859.                     {
  860.                         SetNameMatchString(&nameString);
  861.                         SetTypeMatchString(&typeString);
  862.                         err = MakeOTLookupCall(indx, gNextLookup, &nameString, &typeString);
  863.                             // increment the lookup index in to the zone array for the next
  864.                             // zone to look into.
  865.                         gNextLookup++;
  866.                     }
  867.                 }
  868.             }
  869.             else
  870.             {
  871. #ifdef DEBUG
  872.                 DebugStr("\p T_LKUPNAMECOMPLETE: Unexpected error");
  873. #endif
  874.             }
  875.  
  876.             break;
  877.             
  878.         case T_REGNAMECOMPLETE:
  879.             break;
  880.             
  881.         case T_DELNAMECOMPLETE:
  882.             break;
  883.             
  884.         default:
  885. #ifdef DEBUG
  886.             DebugStr("\pHandleMapperEvents: Unexpected Event!;g");
  887. #endif
  888.             break;
  889.     }
  890. }
  891.  
  892. void    DoEvent(EventRecord *event)
  893. {
  894.     char    key;
  895.  
  896.     switch(event->what) 
  897.     {
  898.  
  899.         case nullEvent:
  900.         case mouseDown:
  901.         case activateEvt:
  902.         case updateEvt:
  903.         case kHighLevelEvent:
  904.         case osEvt:
  905.         case diskEvt:
  906.             break;
  907.  
  908.         case autoKey:
  909.         case keyDown:
  910.             key = event->message & charCodeMask;
  911.             switch (key)
  912.             {
  913.                 case 'q':
  914.                 case 'Q':
  915.                     if (event->modifiers & cmdKey)
  916.                     gDone = true;
  917.                     break;
  918.             }
  919.             break;
  920.  
  921.     }
  922.  
  923. }
  924.